#include "KeyEvent.h"
#include "vmio.h"
#include "UsefullApi.h"
#include "UI/SoftKey.h"

mmi_key_func keyfunc;
VMINT KeyMap[MAX_KEYS][2];
VMINT KeyTypeMap[MAX_KEY_TYPE][2];

void KeyEventInit(void)
{
	VMINT i;
	VMINT t_KeyMap[MAX_KEYS][2]=
	{
		{VM_KEY_NUM0, KEY_0},
		{VM_KEY_NUM1, KEY_1},
		{VM_KEY_NUM2, KEY_2}, 
		{VM_KEY_NUM3, KEY_3}, 
		{VM_KEY_NUM4, KEY_4}, 
		{VM_KEY_NUM5, KEY_5}, 
		{VM_KEY_NUM6, KEY_6}, 
		{VM_KEY_NUM7, KEY_7}, 
		{VM_KEY_NUM8, KEY_8}, 
		{VM_KEY_NUM9, KEY_9}, 
		{VM_KEY_LEFT_SOFTKEY, KEY_LSK},
		{VM_KEY_RIGHT_SOFTKEY, KEY_RSK},
		{VM_KEY_OK, KEY_OK},
		{VM_KEY_UP, KEY_UP},
		{VM_KEY_DOWN, KEY_DOWN},
		{VM_KEY_LEFT, KEY_LEFT},
		{VM_KEY_RIGHT, KEY_RIGHT},
		{VM_KEY_CLEAR, KEY_CLEAR},
		{VM_KEY_STAR, KEY_STAR},
		{VM_KEY_POUND, KEY_POUND},
		{VM_KEY_VOL_UP, KEY_VOL_UP},
		{VM_KEY_VOL_DOWN, KEY_VOL_DOWN},
		{VM_KEY_BACK, KEY_BACK}
	};
	VMINT t_KeyTypeMap[MAX_KEY_TYPE][2]=
	{
		{VM_KEY_EVENT_DOWN, KEY_EVENT_DOWN},
		{VM_KEY_EVENT_UP, KEY_EVENT_UP},
		{VM_KEY_EVENT_LONG_PRESS, KEY_LONG_PRESS},
		{VM_KEY_EVENT_REPEAT, KEY_REPEAT}
	};

	for(i=0;i<MAX_KEYS;i++)
	{
		KeyMap[i][0] = t_KeyMap[i][0];
		KeyMap[i][1] = t_KeyMap[i][1];
	}
	for(i=0;i<MAX_KEY_TYPE;i++)
	{
		KeyTypeMap[i][0] = t_KeyTypeMap[i][0];
		KeyTypeMap[i][1] = t_KeyTypeMap[i][1];
	}
	
	memset(&keyfunc, 0, sizeof(keyfunc));
}

void SetKeyHandle(FuncPtr funcPtr, VMINT16 keyCode, VMINT16 keyType)
{
	if((keyCode < MAX_KEYS) && (keyType < MAX_KEY_TYPE))
	{
    	keyfunc.currKeyFuncPtrs[keyCode][keyType] = funcPtr;
	}
	else
	{
		//assert;
	}
}

void SetGroupKeyHandle(FuncPtr funcPtr, VMINT16 *keysCode, VMINT Len, VMINT16 keyType)
{
	VMINT n = 0;
	if(keysCode == NULL)
	{
		return;
	}

	while(n < Len)
	{
		SetKeyHandle(funcPtr, keysCode[n], keyType);
		n++;
	}	
}

FuncPtr GetKeyHandle(VMINT16 keyCode, VMINT16 keyType)
{
	FuncPtr p = keyfunc.currKeyFuncPtrs[keyCode][keyType];
	if(p)
	{
		return p;
	}
	else
	{
		return NULL;
	}
}

void ClearKeyHandle(VMINT16 keyCode, VMINT16 keyType)
{
	SetKeyHandle(NULL, keyCode, keyType);
}

void ClearAllKeyHandler(void)
{
	VMINT i, j;
	for(i=0;i<MAX_KEYS;i++)
	{
		for(j=0;j<MAX_KEY_TYPE;j++)
		{
			keyfunc.currKeyFuncPtrs[i][j] = NULL;
		}
	}
}

void ClearKeyAllTypeHandle(VMINT16 keyCode)
{
	ClearKeyHandle(keyCode, KEY_EVENT_DOWN);
	ClearKeyHandle(keyCode, KEY_EVENT_UP);
	ClearKeyHandle(keyCode, KEY_LONG_PRESS);
	ClearKeyHandle(keyCode, KEY_REPEAT);
}

void ExecKeyHandle(mmi_key_evt_struct *evt_p)
{
	VMINT i;
	FuncPtr curr_func_ptr;
	
	for(i=0;i<MAX_KEYS;i++)
	{
		if(evt_p->cvt_code == KeyMap[i][0])
		{
			evt_p->mmi_key_code = KeyMap[i][1];
			break;
		}
	}
	for(i=0;i<MAX_KEY_TYPE;i++)
	{
		if(evt_p->cvt_type == KeyTypeMap[i][0])
		{
			evt_p->mmi_key_type = KeyTypeMap[i][1];
			break;
		}
	}
	
	curr_func_ptr = GetKeyHandle(evt_p->mmi_key_code, evt_p->mmi_key_type);

	if((evt_p->mmi_key_code == KEY_LSK) || (evt_p->mmi_key_code == KEY_OK) || (evt_p->mmi_key_code == KEY_RSK))
	{
		//if(curr_func_ptr)
		{
			RedrawSoftKeyByFramework(evt_p->mmi_key_code, evt_p->mmi_key_type);
		}
	}
	
	if(curr_func_ptr)
	{
		(*curr_func_ptr)();
	}
}

void KeyEventHandle(VMINT keyevent, VMINT keycode)
{
	mmi_key_evt_struct evt;
	static BOOL is_key_down = FALSE;
	
    switch (keyevent)
    {
        case VM_KEY_EVENT_DOWN:
            is_key_down = TRUE;
            break;
        
        case VM_KEY_EVENT_LONG_PRESS:
        case VM_KEY_EVENT_REPEAT:
        {
            if (is_key_down == FALSE)
            {
                return;
            }
            break;
        }            

        case VM_KEY_EVENT_UP:
        {
            if (is_key_down == TRUE)
            {
                is_key_down = FALSE;
            }
            else
            {
                return;
            }
            break;
        }

        default:
            break;
    }
	
    evt.cvt_code = keycode;
    evt.cvt_type = keyevent;
    ExecKeyHandle(&evt);
}

void TouchExecKeyHandle(VMINT16 mmi_key_code, VMINT16 mmi_key_type)
{
	FuncPtr curr_func_ptr;
	curr_func_ptr = GetKeyHandle(mmi_key_code, mmi_key_type);
	if(curr_func_ptr)
	{
		(*curr_func_ptr)();
	}
}
